package com.lastproject.ejb.interceptors;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

import javax.faces.context.FacesContext;
import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import com.lastproject.dto.UserDTO;

import annotations.PermissionAnnotation;

public class PermissionInterceptor {

	@PersistenceContext
	EntityManager em;

	@AroundInvoke
	public Object getPermission(InvocationContext ic) throws Exception {

		FacesContext fc = FacesContext.getCurrentInstance();
		Map<String,Object> users =  fc.getExternalContext().getSessionMap();
		UserDTO userDTO = (UserDTO) users.get("userDTO");
		//System.out.println("session: "+ users.keySet().toString());
		//System.out.println(userDTO.getId()+ " ");
		Method method = ic.getMethod();
		Object[] params = ic.getParameters();
		
		PermissionAnnotation meta = method
				.getAnnotation(PermissionAnnotation.class);

		int howMany=0;
		String canAccessLibrary;
		if (meta.canAccessLibrary() == 1) {
			canAccessLibrary = "canAccessLibrary";
			howMany++;
		}
		else{
			canAccessLibrary="";
		}

		String canAssignRights;
		if (meta.canAssignRights() == 1) {
			canAssignRights = "canAssignRights";
			howMany++;
		}
		else{
			canAssignRights = "";
		}

		String canCreateConfidentialReports;
		if (meta.canCreateConfidentialReports() == 1) {
			canCreateConfidentialReports = "canCreateConfidentialReports";
			howMany++;
		}
		else{
			canCreateConfidentialReports = "";
		}

		
		String canCreateGeneralReports;
		if (meta.canCreateGeneralReports() == 1) {
			canCreateGeneralReports = "canCreateGeneralReports";
			howMany++;
		}
		else{
			canCreateGeneralReports = "";
		}

		String canCreateQuiz;
		if (meta.canCreateQuiz() == 1) {
			canCreateQuiz = "canCreateQuiz";
			howMany++;
		}
		else{
			canCreateQuiz = "";
		}

		String canCRUDOnBooks;
		if (meta.canCRUDOnBooks() == 1) {
			canCRUDOnBooks = "canCRUDOnBooks";
			howMany++;
		}
		else{
			canCRUDOnBooks = "";
		}

		String canCRUDOnCandidate;
		if (meta.canCRUDOnCandidate() == 1) {
			canCRUDOnCandidate = "canCRUDOnCandidate";
			howMany++;
		}
		else{
			canCRUDOnCandidate = "";
		}

		String canCRUDOnEmployees;
		if (meta.canCRUDOnEmployees() == 1) {
			canCRUDOnEmployees = "canCRUDOnEmployees";
			howMany++;
		}
		else{
			canCRUDOnEmployees = "";
		}

		String canCRUDOnEmployeesByDepartment;
		if (meta.canCRUDOnEmployeesByDepartment() == 1) {
			canCRUDOnEmployeesByDepartment = "canCRUDOnEmployeesByDepartment";
			howMany++;
		}
		else{
			canCRUDOnEmployeesByDepartment = "";
		}

		String canCRUDOnEmployeesByTeam;
		if (meta.canCRUDOnEmployeesByTeam() == 1) {
			canCRUDOnEmployeesByTeam = "canCRUDOnEmployeesByTeam";
			howMany++;
		}
		else{
			canCRUDOnEmployeesByTeam = "";
		}

		String canCRUDOnEmployeesConfidential;
		if (meta.canCRUDOnEmployeesConfidential() == 1) {
			canCRUDOnEmployeesConfidential = "canCRUDOnEmployeesConfidential";
			howMany++;
		}
		else{
			canCRUDOnEmployeesConfidential = "";
		}

		String canOpenConfidentialReports;
		if (meta.canOpenConfidentialReports() == 1) {
			canOpenConfidentialReports = "canOpenConfidentialReports";
			howMany++;
		}
		else{
			canOpenConfidentialReports = "";
		}
		
		String canOpenGeneralReports="";
		if (meta.canOpenGeneralReports()==1){
			canOpenGeneralReports = "canOpenGeneralReports";
			howMany++;
		}
		else{
			canOpenGeneralReports = "";
		}
		
		String canReviewBook;
		if (meta.canReviewBook() == 1){
			canReviewBook = "canReviewBook";
			howMany++;
		}
		else{
			canReviewBook = "";
		}
 
		List<String> results = em.createQuery("SELECT DISTINCT(rp.name) FROM Role r join "
				+ "r.users ur  "
				+ " join r.permissions rp WHERE ur.id=:id"
				, String.class).setParameter("id", userDTO.getId()).getResultList();
		
		int count=0;
		
		for (String s : results){
			switch(s){
			case "canReviewBook":
				//System.out.println("can review");
				if (!canReviewBook.isEmpty()){
					count++;
				}
				break;
			case "canOpenGeneralReports":
				if (!canOpenGeneralReports.isEmpty()){
					count++;
				}
				break;
			case "canOpenConfidentialReports":
				if (!canOpenConfidentialReports.isEmpty()){
					count++;
				}
				break;
				
			case "canCRUDOnEmployeesConfidential":
				if (!canCRUDOnEmployeesConfidential.isEmpty()){
					count++;
				}
				break;
			
			case "canCRUDOnEmployeesByTeam":
				if (!canCRUDOnEmployeesByTeam.isEmpty()){
					count++;
				}
				break;
			
			case "canCRUDOnEmployeesByDepartment":
				if (!canCRUDOnEmployeesByDepartment.isEmpty()){
					count++;
				}
				break;
				
			case "canCRUDOnEmployees":
				if (!canCRUDOnEmployees.isEmpty()){
					count++;
				}
				break;
				
			case "canCRUDOnCandidate":
				if (!canCRUDOnCandidate.isEmpty()){
					count++;
				}
				break;
				
			case "canCRUDOnBooks":
				if (!canCRUDOnBooks.isEmpty()){
					count++;
				}
				break;
			
			case "canCreateQuiz":
				if (!canCreateQuiz.isEmpty()){
					count++;
				}
				break;
			case "canCreateGeneralReports":
				if (!canCreateGeneralReports.isEmpty()){
					count++;
				}
				break;
			
			case "canCreateConfidentialReports":
				if (!canCreateConfidentialReports.isEmpty()){
					count++;
				}
				break;
			case "canAssignRights":
				if (!canAssignRights.isEmpty()){
					count++;
				}
				break;
			case "canAccessLibrary":
				if (!canAccessLibrary.isEmpty()){
					count++;
				}
				break;
			}
		}

		params[0] = (count!=howMany) ? false : true;
		
		ic.setParameters(params);
		return ic.proceed();
		
	}
}
